package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.MenuTypeEnum;
import com.xbongbong.paas.enums.ProcessSaasFormEnum;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.service.PaasAppService;
import com.xbongbong.paas.service.ProcessSetService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.AppStoreErrorCodeEnum;
import com.xbongbong.pro.template.pojo.TemplateMenuPojo;
import com.xbongbong.pro.template.pojo.TemplatePojo;
import com.xbongbong.pro.template.pojo.dto.TemplateDTO;
import com.xbongbong.pro.template.pojo.vo.TemplateListVO;
import com.xbongbong.pro.template.pojo.vo.TemplateMenuVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.WorkOrderFormEntity;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.WorkOrderFormModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Description:
 *
 * @author 李杰
 * @version v1.0
 * @date 2019/4/1 21:24
 * @since v1.0
 */
@Service("processSetService")
public class ProcessSetServiceImpl implements ProcessSetService {

    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasAppService paasAppService;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private PackageHelp packageHelp;

    @Override
    public TemplateMenuVO getMenuList(TemplateDTO templateDTO) throws XbbException {
        String corpid = templateDTO.getCorpid();
        PaasAppEntity paasAppEntity = paasAppModel.getByKey(templateDTO.getAppId(), corpid);
        if (paasAppEntity == null) {
            throw new XbbException(AppStoreErrorCodeEnum.API_ERROR_300001);
        }
        String paasAppAlias = paasAppEntity.getAlias();
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("del",DelEnum.NORMAL.getDel());
        map.put("appId",templateDTO.getAppId());
        List<PaasMenuEntity> paasMenuEntityList = paasMenuModel.list(map);
        List<PaasFormExplainEntity> paasFormExplainList = paasFormExplainModel.list(map);
        Map<Long, PaasFormExplainEntity> menuIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paasFormExplainList.forEach(item -> menuIdMap.put(item.getMenuId(), item));
        if (!Objects.equals(paasAppAlias, XbbRefTypeEnum.JXC.getAlias())) {
            paasMenuEntityList.removeIf(paasMenuEntity -> !menuIdMap.containsKey(paasMenuEntity.getId()));
        } else {
            paasMenuEntityList.removeIf(paasMenuEntity -> Objects.equals(paasMenuEntity.getSaasMark(), 2) && !menuIdMap.containsKey(paasMenuEntity.getId()));
        }
        // 经销商关闭后需要移除经销商菜单
        paasMenuEntityList.removeIf(item -> Objects.equals(item.getDistributorMark(), DistributorMarkEnum.DISTRIBUTOR.getCode()) && Objects.equals(item.getEnable(), BasicConstant.ZERO));
        List<TemplateMenuPojo> templateMenuPojoList = new ArrayList<>();
        Map<Long, List<TemplateMenuPojo>> menuMap = new HashMap<>(paasMenuEntityList.size());
        boolean isWorkOrderUse = paasAppService.validateAppEnable(null, XbbRefTypeEnum.WORK_ORDER.getAlias(), SaasMarkEnum.SAAS.getCode(), corpid);
        Boolean isUltimate= packageHelp.isUltimateWithFeeType(corpid);
        // 删掉没有解释的系统菜单
        for (PaasMenuEntity entity : paasMenuEntityList) {
            Long parentId = entity.getParentId();
            TemplateMenuPojo templateMenuPojo = new TemplateMenuPojo();
            templateMenuPojo.setAppId(entity.getAppId());
            templateMenuPojo.setMenuName(entity.getName());
            templateMenuPojo.setMenuId(entity.getId());
            templateMenuPojo.setId(entity.getId());
            templateMenuPojo.setType(entity.getType());
            templateMenuPojo.setParentId(entity.getParentId());

            if (Objects.equals(entity.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                String alias = entity.getAlias();
                ProcessSaasFormEnum processSaasFormEnum = ProcessSaasFormEnum.getByAlias(alias);
                if ((processSaasFormEnum == null && !Objects.equals(entity.getType(), MenuTypeEnum.GROUP.getType()))|| (!isWorkOrderUse && Objects.equals(alias, XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getAlias()))) {
                    continue;
                }
                if(!isUltimate && Objects.equals(processSaasFormEnum,ProcessSaasFormEnum.COMPETITOR)){
                    // 竞争对手只在旗舰版展示
                    continue;
                }
            }
            if (Objects.equals(paasAppAlias, XbbRefTypeEnum.JXC.getAlias()) && Objects.equals(parentId, 0L)) {
                // 存放一级菜单
                templateMenuPojoList.add(templateMenuPojo);
            }
            if (Objects.equals(paasAppAlias, XbbRefTypeEnum.JXC.getAlias())) {
                // 获取二级菜单，并放到容器中
                if (Objects.isNull(menuMap.get(parentId))) {
                    List<TemplateMenuPojo> paasMenuList = new ArrayList<>();
                    paasMenuList.add(templateMenuPojo);
                    menuMap.put(entity.getParentId(), paasMenuList);
                } else {
                    List<TemplateMenuPojo> paasMenuList = menuMap.get(parentId);
                    paasMenuList.add(templateMenuPojo);
                    menuMap.put(entity.getParentId(), paasMenuList);
                }
            } else {
                templateMenuPojoList.add(templateMenuPojo);
            }
        }

        // 流程模版进销存分组
        if (Objects.equals(paasAppAlias, XbbRefTypeEnum.JXC.getAlias())) {
            // 分组下没有子菜单，直接删除
            Iterator<TemplateMenuPojo> iterator = templateMenuPojoList.iterator();
            while(iterator.hasNext()){
                TemplateMenuPojo item = iterator.next();
                if(Objects.nonNull(menuMap.get(item.getId())) && !menuMap.get(item.getId()).isEmpty()){
                    // 将子菜单放入父菜单
                    item.setSubMenuList(menuMap.get(item.getId()));
                } else if(Objects.equals(item.getType(), MenuTypeEnum.GROUP.getType())
                        && (Objects.isNull(menuMap.get(item.getId())) || menuMap.get(item.getId()).isEmpty())){
                    iterator.remove();
                    continue;
                }
            }
        }

        TemplateMenuVO templateMenuVO = new TemplateMenuVO();
        templateMenuVO.setMenuList(templateMenuPojoList);
        return templateMenuVO;
    }

    @Override
    public TemplateListVO getFormList(TemplateDTO templateDTO) throws XbbException {
        String corpid = templateDTO.getCorpid();
        Integer saasMark = templateDTO.getSaasMark();
//        boolean isSaas = Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode());
        // 工单
        PaasAppEntity paasAppEntity = paasAppModel.getByKey(templateDTO.getAppId(), corpid);
        if (paasAppEntity == null) {
            throw new XbbException(AppStoreErrorCodeEnum.API_ERROR_300001);
        }
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("del",0);
        map.put("appId",templateDTO.getAppId());
        map.put("menuId", templateDTO.getMenuId());
//        map.put("saasMark", saasMark);
        map.put("enable", 1);
        // 默认查非隐藏菜单
        map.put("hidden", 0);
        List<PaasFormEntityExt> paasFormEntityList = new ArrayList<>();
        if (Objects.equals(paasAppEntity.getAlias(), XbbRefTypeEnum.WORK_ORDER.getAlias())) {
            List<WorkOrderFormEntity> workOrderFormEntityList = workOrderFormModel.findEntitys(map);
            for (WorkOrderFormEntity item : workOrderFormEntityList) {
                PaasFormEntityExt paasFormEntityExt = new PaasFormEntityExt();
                BeanUtil.copyProperties(item, paasFormEntityExt);
                paasFormEntityExt.setSaasMark(SaasMarkEnum.SAAS.getCode());
                paasFormEntityExt.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                paasFormEntityList.add(paasFormEntityExt);
            }
        } else {
            paasFormEntityList = paasFormModel.list(map);
            //过滤掉没有使用权限的多模板表单
            paasFormEntityList = filterNoPermissionForm(paasFormEntityList,templateDTO);
        }
        TemplateListVO templateListVO = new TemplateListVO();
        List<TemplatePojo> templatePojoList = new ArrayList<>();

        for (PaasFormEntityExt paasFormEntityExt : paasFormEntityList){
            if (Objects.equals(paasFormEntityExt.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                boolean isProcess = ProcessSaasFormEnum.containsBusinessType(paasFormEntityExt.getBusinessType());
                if (!isProcess) {
                    continue;
                }
            }

            TemplatePojo templatePojo = new TemplatePojo();
            templatePojo.setIsProcessForm(paasFormEntityExt.getIsProcessForm());
            templatePojo.setAppId(paasFormEntityExt.getAppId());
            templatePojo.setFormId(paasFormEntityExt.getId());
            templatePojo.setFormName(paasFormEntityExt.getName());
            templatePojo.setSaasMark(paasFormEntityExt.getSaasMark());
            templatePojo.setBusinessType(paasFormEntityExt.getBusinessType());
            templatePojo.setMenuId(paasFormEntityExt.getMenuId());
            templatePojo.setDistributorMark(paasFormEntityExt.getDistributorMark());
            templatePojoList.add(templatePojo);
        }
        templateListVO.setFormList(templatePojoList);
        return templateListVO;
    }

    /***
     * 过滤掉没有使用权限的表单
     * @param formList
     * @param templateDTO
     */
    private List<PaasFormEntityExt> filterNoPermissionForm(List<PaasFormEntityExt> formList , TemplateDTO templateDTO){
        List<PaasFormEntityExt> perssionFormList =  new ArrayList<>();
        if(CollectionsUtil.isNotEmpty(formList) && (!Objects.isNull(templateDTO.getLoginUser()))) {
            for(PaasFormEntityExt paasFormEntityExt : formList){
                List<OptionalRangeEntity> optionalRangeList = JSONObject.parseArray(paasFormEntityExt.getPermission(), OptionalRangeEntity.class);
                Boolean noPermission = optionalRangeList != null && !optionalRangeList.isEmpty() && paasFormHelp.haveNoPermission(templateDTO.getLoginUser(), optionalRangeList);
                if (Objects.equals(paasFormEntityExt.getSaasMark(), SaasMarkEnum.SAAS.getCode()) && RedundantTemplateTypeEnum.isMultiTemplate(paasFormEntityExt.getBusinessType()) && noPermission) {
                    continue;
                }
                perssionFormList.add(paasFormEntityExt);
            }
        }
        return  perssionFormList;
    }

}
